package com.firefly.admin.config.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.firefly.admin.common.constant.Constants;
import com.firefly.admin.common.enums.ResultCodeEnum;
import com.firefly.admin.common.utils.RedisUtil;
import com.firefly.admin.common.vo.Result;
import com.firefly.admin.config.entity.FySystemDictionary;
import com.firefly.admin.config.entity.FySystemDictionaryItem;
import com.firefly.admin.config.mapper.FySystemDictionaryItemMapper;
import com.firefly.admin.config.mapper.FySystemDictionaryMapper;
import com.firefly.admin.config.service.FySystemDictionaryItemService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.firefly.admin.config.vo.SystemDictionaryItemQueryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class FySystemDictionaryItemServiceImpl implements FySystemDictionaryItemService {
    @Autowired
    private FySystemDictionaryItemMapper fySystemDictionaryItemMapper;
    @Autowired
    private FySystemDictionaryMapper fySystemDictionaryMapper;

    @Override
    public List<FySystemDictionaryItem> getItemByCode(String dictionaryCode) {
        List<FySystemDictionaryItem> itemList = new ArrayList<>();
        Object cacheValue = RedisUtil.hget(Constants.Redis.CONFIG_KEY, dictionaryCode);
        if (cacheValue != null) {
            if (cacheValue instanceof ArrayList<?>) {
                for (Object o : (List<?>) cacheValue) {
                    itemList.add((FySystemDictionaryItem) o);
                }
            }
        } else {
            LambdaQueryWrapper<FySystemDictionary> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(FySystemDictionary::getDictionaryCode, dictionaryCode);
            List<FySystemDictionary> systemDictionaryList = fySystemDictionaryMapper.selectList(lambdaQueryWrapper);
            if (!CollectionUtils.isEmpty(systemDictionaryList)) {
                FySystemDictionary fySystemDictionary = systemDictionaryList.get(0);
                LambdaQueryWrapper<FySystemDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(FySystemDictionaryItem::getDictionaryId, fySystemDictionary.getDictionaryId());
                itemList = fySystemDictionaryItemMapper.selectList(queryWrapper);
            }
        }
        return itemList;
    }

    /**
     * 分页查询系统字典项目接口
     *
     * @param systemDictionaryItemQueryVo 系统字典项目查询条件
     * @return 字典项目信息列表
     */
    @Override
    public Result<Page<FySystemDictionaryItem>> getSystemDictionaryItemList(SystemDictionaryItemQueryVo systemDictionaryItemQueryVo) {
        log.info("###########FySystemDictionaryItemServiceImpl getSystemDictionaryItemList param = {}", JSONObject.toJSONString(systemDictionaryItemQueryVo));
        Long dictionaryId = systemDictionaryItemQueryVo.getDictionaryId();
        if (dictionaryId == null) {
            return Result.success(null);
        }
        FySystemDictionary systemDictionary = fySystemDictionaryMapper.selectById(dictionaryId);
        if (systemDictionary == null) {
            return Result.getResult(ResultCodeEnum.SYSTEM_DICTIONARY_NOT_FOUND);
        }
        LambdaQueryWrapper<FySystemDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemDictionaryItem::getDictionaryId, dictionaryId);
        queryWrapper.like(StringUtils.isNotBlank(systemDictionaryItemQueryVo.getItemName()), FySystemDictionaryItem::getItemName, systemDictionaryItemQueryVo.getItemName());
        queryWrapper.eq(FySystemDictionaryItem::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        Page<FySystemDictionaryItem> page = new Page<>(systemDictionaryItemQueryVo.getPage(), systemDictionaryItemQueryVo.getLimit());
        Page<FySystemDictionaryItem> dictionaryItemPage = fySystemDictionaryItemMapper.selectPage(page, queryWrapper);
        return Result.success(dictionaryItemPage);
    }

    /**
     * 系统字典项目新增接口
     *
     * @param fySystemDictionaryItem 系统字典项目信息
     * @return 新增结果
     */
    @Override
    public Result<FySystemDictionaryItem> add(FySystemDictionaryItem fySystemDictionaryItem) {
        if (fySystemDictionaryItem == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        ResultCodeEnum resultCodeEnum = checkParam(fySystemDictionaryItem);
        if (resultCodeEnum != null) {
            return Result.getResult(resultCodeEnum);
        }
        int rows = fySystemDictionaryItemMapper.insert(fySystemDictionaryItem);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.ADD_EXCEPTION);
        }
        refreshDictionaryCache(fySystemDictionaryItem.getDictionaryId());
        return Result.success(fySystemDictionaryItem);
    }

    /**
     * 系统字典项目编辑接口
     *
     * @param fySystemDictionaryItem 系统字典项目信息
     * @return 编辑结果
     */
    @Override
    public Result<FySystemDictionaryItem> update(FySystemDictionaryItem fySystemDictionaryItem) {
        if (fySystemDictionaryItem == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        Long itemId = fySystemDictionaryItem.getItemId();
        if (itemId == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        FySystemDictionaryItem systemDictionaryItem = fySystemDictionaryItemMapper.selectById(itemId);
        if (systemDictionaryItem == null) {
            return Result.getResult(ResultCodeEnum.SYSTEM_DICTIONARY_ITEM_NOT_FOUND);
        }
        ResultCodeEnum resultCodeEnum = checkParam(fySystemDictionaryItem);
        if (resultCodeEnum != null) {
            return Result.getResult(resultCodeEnum);
        }
        int rows = fySystemDictionaryItemMapper.updateById(fySystemDictionaryItem);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.UPDATE_EXCEPTION);
        }
        refreshDictionaryCache(fySystemDictionaryItem.getDictionaryId());
        return Result.success(fySystemDictionaryItem);
    }

    /**
     * 系统字典项目删除接口
     *
     * @param itemId 字典项目ID
     * @return 删除结果
     */
    @Override
    public Result<String> delete(Long itemId) {
        if (itemId == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        FySystemDictionaryItem fySystemDictionaryItem = fySystemDictionaryItemMapper.selectById(itemId);
        if (fySystemDictionaryItem == null) {
            return Result.getResult(ResultCodeEnum.SYSTEM_DICTIONARY_ITEM_NOT_FOUND);
        }
        fySystemDictionaryItem.setDeleteFlag(Constants.DeleteFlag.DELETE);
        int rows = fySystemDictionaryItemMapper.updateById(fySystemDictionaryItem);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.DELETE_EXCEPTION);
        }
        refreshDictionaryCache(fySystemDictionaryItem.getDictionaryId());
        return Result.success();
    }


    /**
     * 通过字典ID删除字典项
     *
     * @param dictionaryId 字典ID
     */
    @Override
    public void deleteByDictionaryId(Long dictionaryId) {
        LambdaQueryWrapper<FySystemDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemDictionaryItem::getDictionaryId, dictionaryId);
        FySystemDictionaryItem fySystemDictionaryItem = new FySystemDictionaryItem();
        fySystemDictionaryItem.setDeleteFlag(Constants.DeleteFlag.DELETE);
        fySystemDictionaryItemMapper.update(fySystemDictionaryItem, queryWrapper);
        refreshDictionaryCache(dictionaryId);
    }

    /**
     * 系统字典项目值校验接口
     *
     * @param itemValue 字典项目值
     * @param itemId    字典项目ID
     * @return 校验结果
     */
    @Override
    public Result<String> itemValueCheck(String itemValue, Long itemId, Long dictionaryId) {
        if (StringUtils.isBlank(itemValue)) {
            return Result.getResult(ResultCodeEnum.SYSTEM_DICTIONARY_ITEM_VALUE_NOT_NULL);
        }
        LambdaQueryWrapper<FySystemDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemDictionaryItem::getItemValue, itemValue);
        queryWrapper.eq(FySystemDictionaryItem::getDictionaryId, dictionaryId);
        queryWrapper.eq(FySystemDictionaryItem::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        List<FySystemDictionaryItem> systemDictionaryItemList = fySystemDictionaryItemMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(systemDictionaryItemList)) {
            if (itemId == null) {
                //新增
                return Result.success(ResultCodeEnum.SYSTEM_DICTIONARY_ITEM_EXIST.getMsg());
            } else {
                //编辑
                for (FySystemDictionaryItem systemDictionaryItem : systemDictionaryItemList) {
                    if (itemId.longValue() != systemDictionaryItem.getItemId().longValue()) {
                        return Result.success(ResultCodeEnum.SYSTEM_DICTIONARY_ITEM_EXIST.getMsg());
                    }
                }
            }
        }
        return Result.success();
    }

    /**
     * 通过字典编码获取字典项目列表接口
     *
     * @param dictionaryCode 字典编码
     * @return 校验结果
     */
    @Override
    public Result<List<FySystemDictionaryItem>> getDictionaryItemByCode(String dictionaryCode) {
        if (StringUtils.isBlank(dictionaryCode)) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        log.info("#######getDictionaryItemByCode dictionaryCode = {}", dictionaryCode);
        LambdaQueryWrapper<FySystemDictionary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemDictionary::getDictionaryCode, dictionaryCode);
        queryWrapper.eq(FySystemDictionary::getDictionaryStatus, Constants.Status.ENABLE);
        queryWrapper.eq(FySystemDictionary::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        List<FySystemDictionary> systemDictionaryList = fySystemDictionaryMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(systemDictionaryList) || systemDictionaryList.size() != 1) {
            return Result.getResult(ResultCodeEnum.SYSTEM_DICTIONARY_CODE_REPEAT);
        }
        FySystemDictionary fySystemDictionary = systemDictionaryList.get(0);
        Object cacheValue = RedisUtil.hget(Constants.Redis.DICTION_KEY, dictionaryCode);
        List<FySystemDictionaryItem> systemDictionaryItemList = null;
        if (cacheValue == null) {
            LambdaQueryWrapper<FySystemDictionaryItem> itemQueryWrapper = new LambdaQueryWrapper<>();
            itemQueryWrapper.eq(FySystemDictionaryItem::getDictionaryId, fySystemDictionary.getDictionaryId());
            itemQueryWrapper.eq(FySystemDictionaryItem::getDeleteFlag, Constants.DeleteFlag.NORMAL);
            systemDictionaryItemList = fySystemDictionaryItemMapper.selectList(itemQueryWrapper);
        } else {
            systemDictionaryItemList = new ArrayList<>();
            if (cacheValue instanceof ArrayList<?>) {
                for (Object o : (List<?>) cacheValue) {
                    systemDictionaryItemList.add((FySystemDictionaryItem) o);
                }
            }
        }
        return Result.success(systemDictionaryItemList);
    }

    private ResultCodeEnum checkParam(FySystemDictionaryItem fySystemDictionaryItem) {
        Long dictionaryId = fySystemDictionaryItem.getDictionaryId();
        if (dictionaryId == null) {
            return ResultCodeEnum.REQUEST_PARAM_EXCEPTION;
        }
        FySystemDictionary systemDictionary = fySystemDictionaryMapper.selectById(dictionaryId);
        if (systemDictionary == null) {
            return ResultCodeEnum.SYSTEM_DICTIONARY_NOT_FOUND;
        }
        String itemName = fySystemDictionaryItem.getItemName();
        if (StringUtils.isBlank(itemName)) {
            return ResultCodeEnum.SYSTEM_DICTIONARY_ITEM_NAME_NOT_FOUND;
        }
        String itemValue = fySystemDictionaryItem.getItemValue();
        if (StringUtils.isBlank(itemValue)) {
            return ResultCodeEnum.SYSTEM_DICTIONARY_ITEM_VALUE_NOT_NULL;
        }
        Long itemId = fySystemDictionaryItem.getItemId();
        LambdaQueryWrapper<FySystemDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemDictionaryItem::getDictionaryId, dictionaryId);
        queryWrapper.eq(FySystemDictionaryItem::getItemValue, itemValue);
        queryWrapper.eq(FySystemDictionaryItem::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        List<FySystemDictionaryItem> fySystemDictionaryItems = fySystemDictionaryItemMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(fySystemDictionaryItems)) {
            if (itemId == null) {
                return ResultCodeEnum.SYSTEM_DICTIONARY_ITEM_EXIST;
            } else {
                for (FySystemDictionaryItem systemDictionaryItem : fySystemDictionaryItems) {
                    if (itemId.longValue() != systemDictionaryItem.getItemId().longValue()) {
                        return ResultCodeEnum.SYSTEM_DICTIONARY_ITEM_EXIST;
                    }
                }
            }
        }
        return null;
    }

    private void refreshDictionaryCache(Long dictionaryId) {
        //刷新redis
        FySystemDictionary systemDictionary = fySystemDictionaryMapper.selectById(dictionaryId);
        LambdaQueryWrapper<FySystemDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemDictionaryItem::getDictionaryId, dictionaryId);
        queryWrapper.eq(FySystemDictionaryItem::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        List<FySystemDictionaryItem> itemList = fySystemDictionaryItemMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(itemList)) {
            RedisUtil.hdel(Constants.Redis.DICTION_KEY, systemDictionary.getDictionaryCode());
        } else {
            RedisUtil.hset(Constants.Redis.DICTION_KEY, systemDictionary.getDictionaryCode(), itemList);
        }
    }

    /**
     * 通过字典ID获取字典项列表
     *
     * @param dictionaryId 字典ID
     * @return 字典项列表
     */
    @Override
    public List<FySystemDictionaryItem> findByDictionaryId(Long dictionaryId) {
        LambdaQueryWrapper<FySystemDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemDictionaryItem::getDictionaryId, dictionaryId);
        queryWrapper.eq(FySystemDictionaryItem::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        return fySystemDictionaryItemMapper.selectList(queryWrapper);
    }
}
